/***************************************************************************
 *                                                                         *
 * Copyright (c) 2007 - 2009 Nuvoton Technology Corp. All rights reserved.*
 *                                                                         *
 ***************************************************************************/

/****************************************************************************
* FILENAME
*   adc_demo.c
*
* VERSION
*   1.0
*
* DESCRIPTION
*   The ADC test program of Nuvoton MCU
*
* DATA STRUCTURES
*   None
*
* FUNCTIONS
*
* HISTORY
*   2007-11-23    Ver 1.0 Created
*
* REMARK
*   None
****************************************************************************/
#include <stdio.h>
#include "wblib.h"
#include "NUC900_ADC.h"
#include "nuc900_reg.h"
#include "nuc900_vpost.h"

#define SYNC_TYPE

#define LEN                  8
#define SHIFT                3
#define WIDTH               15
#define LCD_WIDTH          320
#define AXIS_X1             60
#define AXIS_Y1             60 
#define AXIS_X2            180
#define AXIS_Y2             60   
#define AXIS_X3             60
#define AXIS_Y3            260
#define AXIS_X4            260
#define AXIS_Y4            180


//#define AXIS_X2             60
//#define AXIS_Y2            180   
//#define AXIS_X3            260
//#define AXIS_Y3             60

INT    volatile LCD_BUFF_BASE;
UINT8  volatile STATE;
//UINT32 volatile pre_x,pre_y;

INT   COUNT;
INT32 handler;

short ADCDataIn()
{
    INT16 valueX, valueY;
    adcRead(&valueX, &valueY, 1);
    
    valueX = (valueX*5)>>4;
	valueY = (valueY*15)>>6;
	valueY = 240 - valueY; //for AUO panel
    *(short*)(LCD_BUFF_BASE+(valueY*LCD_WIDTH+valueX)*2) = 0x1f;
	
	return 0;
}

INT32 ADCCallback(UINT32 status, UINT32 userData)
{
	if (STATE == 1)
	{
	   STATE = 2;
	   adcIoctl(ADC_TSC_XY_CTL, 1, 0);
	   
	   adcIoctl(START_CONV, 0, 0);   
	}	
    
    else  //(STATE == 2)
    {
       ADCDataIn();

       adcIoctl(ADC_INT_OFF, 0, 0);
       adcChangeTscMode(TRIG);       
       
       writew(REG_TICR0,5000);
       writew(REG_TCSR0,0x60000000);
    }
    
    return 0;
}

INT32 WTCallback(UINT32 status, UINT32 userData)
{
	if (STATE == 0)
	{
	   STATE = 1;
	   COUNT = 0;
	   
	   adcIoctl(ADC_TSC_XY_CTL, 0, 0);
	   adcIoctl(WT_INT_OFF, 0, 0);
	   adcIoctl(ADC_INT_ON, (UINT32)ADCCallback, (UINT32)handler);
	   adcChangeTscMode(SEMIAUTO);
	   adcIoctl(START_CONV, 0, 0);
	}	
    return 0;
}

VOID timer0_irq()
{
	//UINT32 tmp32;
	
	writew(REG_TISR,0x1);//clear timer0 interrupt
	writew(REG_TCSR0,0L);//disable timer0
	
    //printf("state 3\n");	
	if((readw(REG_ADC_TSC) & 0x1) == 0x1) //down
	{
		writew(REG_ADC_TSC,0x0); // x position
		
		adcChangeTscMode(SEMIAUTO);
		
		adcIoctl(ADC_INT_ON, (UINT32)ADCCallback, (UINT32)handler);
				
		adcIoctl(WT_INT_OFF, 0, 0);
		
		adcIoctl(START_CONV, 0, 0);

		STATE = 1;
		
	}
	else
	{
 	    
    	adcIoctl(WT_INT_ON, (UINT32)WTCallback, (UINT32)handler); 

    	adcIoctl(ADC_INT_OFF, 0, 0);

		adcChangeTscMode(TRIG);

		STATE = 0;
	}	
	return;
}


INT main(VOID)
{
   
    WB_PLL_T  sysClock;   //declare a structure variable of system clock configuration
    WB_UART_T my_uart;

    LCDFORMATEX lcdformatex;
    UINT32      * pframbuf = NULL;
    UINT32      tmp32;
    INT         i;
       
    sysClock.pll0 = PLL_100MHZ;					//PLL0 output clock
	//sysClock.pll1 = PLL_166MHZ;				//PLL1 output clock
	
	sysClock.cpu_src = CPU_FROM_PLL0;		    //Select CPU clock source
	sysClock.ahb_clk = AHB_CPUCLK_1_1;	        //Select AHB clock divider
	sysClock.apb_clk = APB_AHB_1_8;			    //Select APB clock divider
	sysSetPLLConfig(&sysClock);					//Call system function call
//#define CACHE_ON	
#ifdef CACHE_ON   
    sysInvalidCache();
    sysEnableCache(CACHE_WRITE_BACK);
    //sysFlushCache(I_D_CACHE);
#endif       
      
	my_uart.uiFreq     = 15000000;              /* 15MHZ */
	my_uart.uiBaudrate = 115200;
	my_uart.uiDataBits = WB_DATA_BITS_8;
	my_uart.uiStopBits = WB_STOP_BITS_1;
	my_uart.uiParity   = WB_PARITY_NONE;
	my_uart.uiRxTriggerLevel = LEVEL_8_BYTES;
	
	sysInitializeUART(&my_uart);    
    
    
	/* enable the TIMER0 clock */
	tmp32 = readw(REG_CLKEN);
	tmp32 = tmp32 | 0x00080000;
  	writew(REG_CLKEN,tmp32);    
  	
#if 0    
    outpw(0xB0000200,inpw(0xB0000200) &~1);        //LCD clock off
    outpw(0xB0000210,0x00001A03);                  //PLL1 = 162Mhz
#ifdef SYNC_TYPE	
	outpw(0xB0000208,readw(0xB0000208) | (5<<12)); //CPU:AHB:VCK=1:1:1/6 , Sync type
#endif	
		
	for (i=0; i<0x70000; i++);
	
#ifdef SYNC_TYPE	

	//outpw(0xB0000204,inpw(0xB0000204) &~(3<<6) | (1<<6)); //video from PLL1 , Sync type
	outpw(0xB0000204,(inpw(0xB0000204)&0xffffff3c)|0x40 );  //video from PLL1 , Sync type //WT
#endif

	outpw(0xB0000200,inpw(0xB0000200) | 1);                 //LCD clock on    
	
#endif //cmn	
    sysSetLocalInterrupt(ENABLE_IRQ);
    
    /* ----------Video Initialization (Display_Continus)-----------------  */    

    lcdformatex.ucVASrcFormat = VA_SRC_RGB565;
	vpostLCMInit(&lcdformatex);
	pframbuf = vpostGetFrameBuffer();
	LCD_BUFF_BASE = (int) pframbuf;
    for (i=0;i<320*240;i++)
    {
    	*pframbuf++ = 0;
    }    
    
	writew(REG_TCSR0,0L);
	writew(REG_TISR,0x1);
	sysSetInterruptType(IRQ_TIMER0, HIGH_LEVEL_SENSITIVE);
	sysInstallISR(IRQ_LEVEL_1, IRQ_TIMER0, (PVOID)timer0_irq);
	sysSetLocalInterrupt(ENABLE_IRQ);                            
	sysEnableInterrupt(IRQ_TIMER0); 
    
    
    adcInit();
    handler = adcOpen(TRIG, 4, AIN0);
    adcIoctl(TSC_TYPE_SW, WIRE4, 0);
    adcIoctl(ADC_DELAY, 0x10000, 0);
    
    //handler = adcOpen(TRIG, 4, AIN0);
    adcIoctl(WT_INT_ON, (UINT32)WTCallback, (UINT32)handler);
    STATE = 0;

    

    while(1);



#if 0    
    adcIoctl(ADC_INT_ON, (UINT32)AdcCallback, (UINT32)handler);
    
    while(1)
    {
      adcIoctl(START_CONV, 0, 0);
    
      while(!adcReady);
	  adcReady = FALSE;
	
	  adcRead(&valueX, &valueY, 1);
      printf("%d\n",valueX);
    }
    adcClose();
#endif
 return 0;
}
